package org.adit.spring.hibernate.controller;

import java.io.FileNotFoundException;
import java.rmi.RemoteException;
import java.util.Date;
import java.util.List;

import org.adit.spring.hibernate.component.RouteSession;
import org.adit.spring.hibernate.dao.RouteDao;
import org.adit.spring.hibernate.entity.ParametrosRoute;
import org.adit.spring.hibernate.entity.Ponto;
import org.adit.spring.hibernate.entity.Recurso;
import org.adit.spring.hibernate.entity.Route;
import org.adit.spring.hibernate.infra.Restrito;
import org.adit.spring.hibernate.parser.Parser;
import org.adit.spring.hibernate.parser.entity.FleetEngineInput;
import org.adit.spring.hibernate.parser.entity.FleetEngineOutput;
import org.adit.spring.hibernate.parser.entity.Job;
import org.adit.spring.hibernate.service.XmlService;
import org.tempuri.IRWFleetEngineProxy;

import br.com.caelum.vraptor.Delete;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Put;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.view.Results;

@Resource
public class RoutesController {

	private final Result result;
	private RouteDao dao;
	private XmlService xmlService;
	private RouteSession routeSession;

	public RoutesController(RouteSession routeSession, RouteDao dao, XmlService xmlService, Result result) {
		this.routeSession = routeSession;
		this.dao = dao;
		this.xmlService = xmlService;
		this.result = result;
	}

	@Restrito
	@Get
	@Path("/routes/demo")
	public void demo() {

	}

	@Restrito
	@Post
	@Path("/routes")
	public void adiciona(Route route) {

		Route routeRef = new Route();
		routeRef = dao.carrega(route.getId());
		route = routeRef;
		routeSession.setRoute(route);

		xmlService.salva(route);
		result.redirectTo(RoutesController.class).lista(route.getId());
	}

	// Returna uma pagina com o progressbar
	@Post
	@Path("/routes/xmlin")
	public Route xmlin(Route route) {
		System.out.println(route.getXml());
		xmlService.xmlin(route);
		return route;
	}

	// TODO Para controlar o status/stop/getResult
	@Get
	@Path("/routes/cpxml")
	public Route controlFleet(ParametrosRoute parametrosRoute) throws RemoteException, FileNotFoundException {
		Route route = dao.carrega(parametrosRoute.getId());
		route.setTipoRequisicao(parametrosRoute.getTipo());

		IRWFleetEngineProxy fleetClient = new IRWFleetEngineProxy();
		String osID = route.getOptimizeStartID();
		String xmlOutput = "";
		FleetEngineOutput fleetEngineOutput = null;

		try {
			switch (parametrosRoute.getTipo()) {
			case 0: // getStatus
				// TODO: Redirecionar para um Ajax
				route.setStatusFleet(fleetClient.getStatus(osID));
				break;
			case 1: // getResults
				xmlOutput = fleetClient.getResult(osID);
				fleetEngineOutput = buscaXmlOutput(xmlOutput);
				route.setXmlOutput(xmlOutput);
				dao.atualiza(route);
				// parametrosRoute.setFleetEngineOutput(fleetEngineOutput);
				break;
			default: // optimizeStop <> 1 e <> 0
				if (fleetClient.optimizeStop(osID)) {
					xmlOutput = fleetClient.getResult(osID);
					System.out.println(xmlOutput);
					fleetEngineOutput = buscaXmlOutput(xmlOutput);

					route.setXmlOutput(xmlOutput);
					// parametrosRoute.setFleetEngineOutput(fleetEngineOutput);
					dao.atualiza(route);
					// result.include(fleetEngineOutput);
					//result.redirectTo(RoutesController.class).results(fleetEngineOutput);
				}

				break;
			}
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		result.include(fleetEngineOutput);
		return route;
	}

	@Restrito
	@Get
	@Path("/routesPower")
	public FleetEngineOutput resultado(Long idBusca) throws FileNotFoundException {

		Parser parser = new Parser();
		Route route = dao.busca(routeSession.getRoute().getId());
		System.out.println("entregas");
		for (Ponto ponto : route.getPontos()) {
			System.out.println(ponto.getX());
			System.out.println(ponto.getY());

		}

		// TODO: ENVIAR ESSE XML PARA O WEB SERVICE
		String xmlIn = xmlService.getXmlIn(routeSession.getRoute().getId());
		// Web Service - Call

		// TODO: FAZER o getXmlOut!!!  PEGAR O XML DO RETORNO DO WEB SERVICE  :  xmlService.getXmlIn(routeSession.getRoute().getId())
		FleetEngineOutput fleetEngineOutput = parser.getXmlOutput("");

		// STATIC MAP
		// http://maps.googleapis.com/maps/api/staticmap?size=256x256&maptype=roadmap&
		// markers=color:blue|label:1|40.702147,-74.015794&markers=color:green|label:c|40.711614,-74.012318&
		// markers=color:red|color:red|label:C|40.718217,-73.998284&sensor=false
		FleetEngineInput fleetEngineInput = parser.getXmlInput(xmlService.getXmlIn(routeSession.getRoute().getId()));
		String url = "http://maps.google.com/maps?saddr=-20.89175,-41.09270&daddr=-22.5788,-41.9879";
		for (Job job : fleetEngineInput.getJobs()) {
			System.out.println(job.getPickup().getX());
			url = url + "+to:" + job.getPickup().getX() + ",";
			System.out.println(job.getPickup().getY());
			url = url + job.getPickup().getY();

		}
		url = url + "&hl=en&ll=-21.897181,-41.846924&spn=2.660359,5.410767&sll=-21.897181,-41.781006&sspn=2.660359,5.410767&geocode=FZo3wf4dpPmM_Q%3BFZB5p_4dxFB__Q%3BFRDvov4dHPR5_Q%3BFexYo_4daMZ5_Q%3BFbz8ov4dYL95_Q%3BFch9ov4d3OB3_Q%3BFbCzov4d2NB3_Q%3BFRQNqf4dyIt8_Q&mra=ls&t=h&z=8";
		System.out.println(url);

		return fleetEngineOutput;
	}

	//@Get
	//@Path("/routes/results")
	//public void results(FleetEngineOutput fleetEngineOutput) {
	//	result.include(xmlService.setResults(fleetEngineOutput));
	//	result.include(fleetEngineOutput);
	//}

	@Restrito
	@Get
	@Path("/routes/novo")
	public void formulario() {

	}

	@Restrito
	@Get
	@Path("/routes/{id}")
	public Route edita(Long id) {
		return dao.carrega(id);
	}

	@Restrito
	@Put
	@Path("/routes/{route.id}")
	public void altera(Route route) {
		dao.atualiza(route);
		result.redirectTo(RoutesController.class).lista(route.getId());
	}

	@Restrito
	@Delete
	@Path("/routes/{id}")
	public void remove(Long id) {
		Route route = dao.carrega(id);
		dao.remove(route);
		result.redirectTo(RoutesController.class).lista(route.getId());
	}

	@Get
	@Path("/routes")
	public List<Route> lista(Long id) {
		for (Route route : dao.listaTudo()) {
			for (Recurso recurso : route.getRecursos()) {
				System.out.println(recurso.getResourceTypeId());
			}
		}
		return dao.listaTudo();
	}

	@Get
	@Path("/routes/busca")
	public void busca() {
		Route route = new Route();
		FleetEngineOutput fleetEngineOutput = new FleetEngineOutput();
		try {

			fleetEngineOutput = buscaXmlOutput("");
			for (Job job : fleetEngineOutput.getJobs()) {
				System.out.println(job.getResource());
			}
			route.setData(new Date());
			// pRoute.setDescricao(fleetEngineOutput.getResult().getDrivetime());

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		// result.include("fleetEngineOutput", fleetEngineOutput);
		// result.include("route", route);
		// return route;
		//result.redirectTo(RoutesController.class).results(fleetEngineOutput);
	}

	public FleetEngineOutput buscaXmlOutput(String xmlIdentifier) throws FileNotFoundException {
		Parser parser = new Parser();
		return parser.getXmlOutput(xmlIdentifier);
	}

	public FleetEngineInput buscaXmlInput(String xmlIdentifier) throws FileNotFoundException {
		Parser parser = new Parser();
		return parser.getXmlInput(xmlIdentifier);
	}

	public List<Route> busca(String nome) {
		result.include("nome", nome);
		return dao.buscaLista(nome);
	}

	@Get
	@Path("/routes/busca.json")
	public void buscaJson(String q) {
		result.use(Results.json()).from(dao.buscaLista(q)).exclude("id", "descricao").serialize();
	}
}